import { ref, effectScope, markRaw } from "vue";
import { setActivePinia, SymbolPinia } from "./rootStore";

export function createPinia() {
  // 创建一个独立的获取内部响应式的空间
  const scope = effectScope(true);
  // run方法的返回值就是里面回调函数的返回值
  // 目的是方便统一管理/停止收集依赖
  const state = scope.run(() => ref({}));
  // 存放插件的
  const _p = [];
  // 防止用户把创建的pinia进一步进行响应式处理,用markRaw包一下禁止响应式
  const pinia = markRaw({
    install(app) {
      // 保存一下全局的pinia
      setActivePinia(pinia);
      // 把pinia共享出去,将pinia实例暴露(provide)在全局(app)上
      // 使用时注入(inject)进来就行了
      pinia._a = app;
      app.provide(SymbolPinia, pinia);
      // 为了能让vue2正常使用把pinia也挂全局一份
      app.config.globalProperties.$pinia = pinia;
    },
    // 注册插件的方法,可以写一些所有仓库共用的东西
    use(plugin){
      _p.push(plugin);
      return this;
    },
    _p, // 保存插件
    _a: null, // install时会将app附在这上
    state, // 所有的状态
    _e: scope, // 用来管理整个应用的effectScope
    _s: new Map(), // 记录所有的store
  });
  return pinia;
}